"""
读取配置文件，下载文件到指定目录
"""
import os
import re
import yaml
from gitlab_tools import syncGitlab

class Docs:

    def __init__(self, config, gitlab):
        self.config = config
        self.gitlab = gitlab
        self.gl = syncGitlab(gitlab["url"], gitlab["accessToken"])

    def load(self):
        # print(self.config)
        documents = self.config["docs"]
        self.load_files(documents, 0, "") # 遍历下载文件
        nodes = []
        self.convert_to_list(documents, nodes, 0)
        self.write_sidebar(self.config["path"] + "_sidebar.md", nodes)

    # 遍历下载文件
    def load_files(self, nodes, depth, parent_path_pref):
        for node in nodes:

            if "path_pref" not in node and parent_path_pref is not None:
                node["path_pref"] = parent_path_pref

            # print(parent_path_pref, ">>>", node["path_pref"])

            if "path" in node and node["path"] is not None:
                path = self.parse_file_path(node["path"])
                node["relative_path"] = self.download_file(path)
                # 文档内容处理
                self.add_read_origin(node)
            if "docs" in node and node["docs"] is not None:                
                self.load_files(node["docs"], depth + 1, node["path_pref"])
    
    # 解析文件地址
    def parse_file_path(self, url):
        path = url.replace(self.gitlab["url"] + "/", "").split("/-/blob/")
        # 项目名
        project_name = path[0]
        # url 文件地址
        file_paths = path[1].split("/", 1)
        # 分支
        branch = file_paths[0]
        # 文件路径
        file_path = file_paths[1]
        # print(project_name, branch, file_path)
        return {
            "project_name": project_name,
            "branch": branch,
            "file_path": file_path
        }
        
    # 下载文件
    def download_file(self, path):
        project = self.gl.get_project_by_name(path["project_name"])
        file_path = path["file_path"]
        to_path = os.path.join(self.config["path"], path["project_name"], file_path)
        # 文件所在目录
        dirs = os.path.dirname(to_path)
        if not os.path.exists(dirs):
            os.makedirs(dirs)
        self.gl.get_content(project, path["branch"], file_path, to_path)
        return to_path

    # 文件目录 tree 转 list
    def convert_to_list(self, tree, nodes, depth):
        if tree is not None:
            for node in tree:
                node["depth"] = depth
                nodes.append(self.format_title(node))
                if "docs" in node:
                    self.convert_to_list(node["docs"], nodes, depth + 1)

    # 格式化标题, 生成md格式的层级目录
    @staticmethod
    def format_title(node):
        title = node["name"]
        depth = node["depth"]

        if "relative_path" in node and node["relative_path"] is not None:
            path = node["relative_path"]
            if not path.startswith("/"):
                path = "/" + path
            return "  " * depth + "- [%s](%s)" % (title, path)
        else:
            return "  " * depth + "- %s" % (title)

    # 写入目录文件
    @staticmethod
    def write_sidebar(dir, nodeList):
        with open(dir, 'w', encoding="utf-8") as f:
            f.writelines('\n'.join(nodeList))

    # 文档底部追加 阅读原文 链接
    # path 路径追加前辍
    def add_read_origin(self, path):
        if "path_pref" in path and path["path_pref"]:
            self.add_path_pref(path, path["path_pref"])
        with open(path["relative_path"], 'a') as f:
            f.write("\n\n\n\n  [阅读原文](%s)" % path["path"])

    # path 前辍增加
    def add_path_pref(self, path, path_pref):
        line = []
        # 读取文件
        with open(path["relative_path"], 'r') as f1:
            for ln in f1.readlines():
                # 判断是否有 **Path** 开头
                if re.match(r'^\s*\*\*Path.{0,1}\*\*', ln, re.I):
                    path_pref = path["path_pref"]
                    ln = re.sub('(?<=\`)(?P<path>.+)?(?=\`$)', lambda line: self.sub_path_title(line, path_pref), ln)
                line.append(ln)
        # 写回文件
        with open(path["relative_path"], 'w') as f:
            f.writelines(line)

    # path 前辍替换
    def sub_path_title(self, matched, path_pref):
        # print(matched.group("path"), path_pref)
        path = matched.group("path")
        if not path.startswith(path_pref):
            return path_pref + path
        else:
            return path
        
if __name__ == "__main__":
    with open("source/config.yml", 'r') as f:
        config = yaml.load(f, Loader = yaml.FullLoader)
        Docs(config, config["gitlab"]).load()
    
